'use client'

import { createClient } from "@connectrpc/connect";
import { createConnectTransport } from "@connectrpc/connect-web";
import { useRef, useState, useEffect } from "react";
import { CalculatorService } from "../gen/pts/f/v1/calculator_pb";

type gRPCRequest = {
  "prior": number | null,
  "post": number | null,
  "op": number | null, // 0: +, 1: -, 2: *, 3: / 
}

type gRPCResponse = {
  "result": number | null,
}

export default function ClientCalculator() {
  const [mounted, setMounted] = useState(false);
  
  useEffect(() => {
    setMounted(true);
  }, []);

  const transport = createConnectTransport({
    baseUrl: "http://localhost:8080"
  });
  const opReq = useRef<gRPCRequest>({
    "prior": null,
    "post": null,
    "op": null,
  })
  let [board, setBoard] = useState(0);
  let [op, setOp] = useState<number | null>(null);
  let [isNegative, setNegative] = useState(0);
  let [isErr, setErr] = useState(false);
  let [justCalculated, setJustCalculated] = useState(false); // 新增：标记是否刚计算完
  let [needsNewNumber, setNeedsNewNumber] = useState(false); // 新增：标记是否需要开始新数字

  let push = (n: number) => {
    if (isErr) {
      setErr(false);
    }
    
    // 处理清除和退格
    if (n === -1) { // 清除
      opReq.current = { prior: null, post: null, op: null };
      setBoard(0);
      setOp(null);
      setJustCalculated(false);
      setNeedsNewNumber(false);
      setNegative(0);
      return;
    }
    
    if (n === -2) { // 退格
      setBoard(Math.floor(board / 10));
      if (board === 0 && isNegative === 1) {
        setNegative(0);
      }
      setJustCalculated(false);
      return;
    }
    
    // 如果刚计算完且输入数字，重置状态开始新计算
    if (justCalculated && n >= 0 && n <= 9) {
      setJustCalculated(false);
      setNeedsNewNumber(false);
      opReq.current = { prior: null, post: null, op: null };
      setOp(null);
      setBoard(n);
      return;
    }
    
    // 如果需要新数字（刚按了运算符），开始新数字
    if (needsNewNumber && n >= 0 && n <= 9) {
      setNeedsNewNumber(false);
      setBoard(n);
      setJustCalculated(false);
      return;
    }
    
    // 大数限制
    if (board >= 99999999 && n >= 0 && n <= 9) {
      return;
    }
    
    // 数字输入逻辑
    if (n >= 0 && n <= 9) {
      if (board === 0) {
        setBoard(n);
      } else {
        setBoard(board * 10 + n);
      }
      setJustCalculated(false);
    }
  }
  let pressOp = (pop: number) => {
    if (pop === op) {
      console.debug("press same op")
      setOp(null);
      return;
    }
    
    // 如果之前有运算符且有完整的表达式，先计算
    if (opReq.current.prior !== null && opReq.current.op !== null && !justCalculated) {
      calc().then(() => {
        // 计算完成后设置新的运算符
        setOp(pop);
        opReq.current.op = pop;
        setJustCalculated(false);
        setNeedsNewNumber(true);
      });
    } else {
      // 设置运算符
      opReq.current.prior = board * (isNegative === 1 ? -1 : 1);
      setNegative(0);
      setOp(pop);
      opReq.current.op = pop;
      setJustCalculated(false);
      setNeedsNewNumber(true); // 标记需要新数字
    }
  }
  let calc = async () => {
    console.debug("calc called, opReq:", opReq.current);
    
    if (opReq.current.prior === null || opReq.current.op === null) {
      console.debug("Incomplete expression, skipping calculation");
      return;
    }
    
    if (opReq.current.post === null) {
      opReq.current.post = board * (isNegative === 1 ? -1 : 1);
      setNegative(0);
    }
    
    console.debug("Calculating:", opReq.current);
    
    try {
      const res = await toBak(opReq.current);
      console.debug("Calculation result:", res);
      
      if (res.result === null) {
        setBoard(0);
        setJustCalculated(true);
        return;
      }
      
      setBoard(Math.abs(res.result));
      if (res.result < 0) {
        setNegative(1);
      } else {
        setNegative(0);
      }
      
      setOp(null);
      // 重要：将结果设为下次计算的prior，并重置post
      opReq.current.prior = res.result;
      opReq.current.post = null;
      opReq.current.op = null;
      setJustCalculated(true);
      
    } catch (error) {
      console.error("Calculation error:", error);
      setErr(true);
      setBoard(0);
      setJustCalculated(true);
    }
  }
  let toBak = async (req: gRPCRequest) => {
    const client = createClient(CalculatorService, transport);
    const res = await client.calculate({
      prior: req.prior!,
      post: req.post!,
      op: req.op!,
    });
    console.debug("remote response is", res);
    return { result: res.result };
  }

  if (!mounted) {
    return null;
  }

  return (
    <div style={{
      minHeight: '100vh',
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      justifyContent: 'center',
      backgroundColor: '#f3f4f6'
    }}>
      <div style={{
        backgroundColor: 'white',
        borderRadius: '8px',
        boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
        padding: '24px'
      }}>
        <div style={{
          display: 'grid',
          gridTemplateColumns: 'repeat(4, 1fr)',
          gap: '12px',
          width: '320px'
        }}>
          {/* Display */}
          <div style={{
            gridColumn: 'span 4',
            backgroundColor: 'black',
            color: 'white',
            textAlign: 'right',
            fontSize: '24px',
            padding: '16px',
            borderRadius: '4px',
            marginBottom: '16px',
            minHeight: '64px',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'end',
            position: 'relative'
          }}>
            {isNegative ? '-' : ''}{board}
            {isErr && <div style={{position: 'absolute', top: '4px', left: '4px', fontSize: '12px', color: '#f87171'}}>ERR</div>}
            {justCalculated && <div style={{position: 'absolute', top: '4px', right: '4px', fontSize: '10px', color: '#10b981'}}>✓</div>}
          </div>

          {/* Row 1 */}
          <button 
            style={{
              backgroundColor: '#e5e7eb',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => setNegative(isNegative === 0 ? 1 : 0)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#e5e7eb'}
          >
            ±
          </button>
          <button 
            style={{
              backgroundColor: '#e5e7eb',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => push(-1)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#e5e7eb'}
          >
            C
          </button>
          <button 
            style={{
              backgroundColor: '#e5e7eb',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => push(-2)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#e5e7eb'}
          >
            ⌫
          </button>
          <button 
            style={{
              backgroundColor: op === 3 ? '#ea580c' : '#fb923c',
              color: 'white',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => pressOp(3)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#ea580c'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = op === 3 ? '#ea580c' : '#fb923c'}
          >
            ÷
          </button>

          {/* Row 2 */}
          <button 
            style={{
              backgroundColor: '#d1d5db',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => push(7)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#9ca3af'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
          >
            7
          </button>
          <button 
            style={{
              backgroundColor: '#d1d5db',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => push(8)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#9ca3af'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
          >
            8
          </button>
          <button 
            style={{
              backgroundColor: '#d1d5db',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => push(9)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#9ca3af'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
          >
            9
          </button>
          <button 
            style={{
              backgroundColor: op === 2 ? '#ea580c' : '#fb923c',
              color: 'white',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => pressOp(2)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#ea580c'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = op === 2 ? '#ea580c' : '#fb923c'}
          >
            ×
          </button>

          {/* Row 3 */}
          <button 
            style={{
              backgroundColor: '#d1d5db',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => push(4)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#9ca3af'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
          >
            4
          </button>
          <button 
            style={{
              backgroundColor: '#d1d5db',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => push(5)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#9ca3af'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
          >
            5
          </button>
          <button 
            style={{
              backgroundColor: '#d1d5db',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => push(6)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#9ca3af'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
          >
            6
          </button>
          <button 
            style={{
              backgroundColor: op === 1 ? '#ea580c' : '#fb923c',
              color: 'white',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => pressOp(1)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#ea580c'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = op === 1 ? '#ea580c' : '#fb923c'}
          >
            −
          </button>

          {/* Row 4 */}
          <button 
            style={{
              backgroundColor: '#d1d5db',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => push(1)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#9ca3af'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
          >
            1
          </button>
          <button 
            style={{
              backgroundColor: '#d1d5db',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => push(2)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#9ca3af'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
          >
            2
          </button>
          <button 
            style={{
              backgroundColor: '#d1d5db',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => push(3)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#9ca3af'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
          >
            3
          </button>
          <button 
            style={{
              backgroundColor: op === 0 ? '#ea580c' : '#fb923c',
              color: 'white',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => pressOp(0)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#ea580c'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = op === 0 ? '#ea580c' : '#fb923c'}
          >
            +
          </button>

          {/* Row 5 */}
          <button 
            style={{
              gridColumn: 'span 2',
              backgroundColor: '#d1d5db',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => push(0)}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#9ca3af'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#d1d5db'}
          >
            0
          </button>
          <button 
            style={{
              backgroundColor: '#d1d5db',
              color: 'black',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
          >
            .
          </button>
          <button 
            style={{
              backgroundColor: '#fb923c',
              color: 'white',
              fontWeight: '500',
              padding: '16px',
              borderRadius: '4px',
              border: 'none',
              cursor: 'pointer'
            }}
            onClick={() => calc()}
            onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#ea580c'}
            onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#fb923c'}
          >
            =
          </button>
        </div>
      </div>
    </div>
  );
}